//
//  HHFlutterRouter.swift
//  HHPatient
//
//  Created by Basic. on 2021/8/10.
//  flutter 路由

import flutter_boost

public class FLBRouter: NSObject, FlutterBoostDelegate {
    // MARK: - proerty

    /// 当前导航控制器
    var navigationController: UINavigationController {
        return topNavigation() ?? UINavigationController()
    }

    /// 用来存返回flutter侧返回结果的表
    var resultTable: Dictionary<String, ([AnyHashable: Any]?) -> Void> = [:]

    // MARK: - 初始化设置

    public static func setup(_ application: UIApplication, _ onStart: ((FlutterEngine?) -> Void)?) {
        let router = FLBRouter()
        FlutterBoost.instance()?.setup(application, delegate: router, callback: { engine in
            onStart?(engine)
        })
    }

    // MARK: - FlutterBoostDelegate

    public func pushNativeRoute(_ pageName: String!, arguments: [AnyHashable: Any]!) {
        // 可以用参数来控制是push还是pop
        let isPresent = arguments["isPresent"] as? Bool ?? false
        let isAnimated = arguments["isAnimated"] as? Bool ?? true
        // 这里根据pageName来判断生成哪个vc
        let targetViewController = routeViewController(pageName, arguments: arguments)
        if isPresent {
            navigationController.present(targetViewController, animated: isAnimated, completion: nil)
        } else {
            navigationController.pushViewController(targetViewController, animated: isAnimated)
        }
    }

    public func pushFlutterRoute(_ options: FlutterBoostRouteOptions!) {
        let vc: FBFlutterViewContainer = FBFlutterViewContainer()
        vc.setName(options.pageName, uniqueId: options.uniqueId, params: options.arguments, opaque: options.opaque)

        // 用参数来控制是push还是pop
        let isPresent = (options.arguments?["isPresent"] as? Bool) ?? false
        let isAnimated = (options.arguments?["isAnimated"] as? Bool) ?? true

        // 对这个页面设置结果
        resultTable[options.pageName] = options.onPageFinished

        // 如果是present模式 ，或者要不透明模式，那么就需要以present模式打开页面
        if isPresent || !options.opaque {
            navigationController.present(vc, animated: isAnimated, completion: nil)
        } else {
            navigationController.pushViewController(vc, animated: isAnimated)
        }
    }

    public func popRoute(_ options: FlutterBoostRouteOptions!) {
        // 如果当前被present的vc是container，那么就执行dismiss逻辑
        if let vc = navigationController.presentedViewController as? FBFlutterViewContainer, vc.uniqueIDString() == options.uniqueId {
            // 这里分为两种情况，由于UIModalPresentationOverFullScreen下，生命周期显示会有问题
            // 所以需要手动调用的场景，从而使下面底部的vc调用viewAppear相关逻辑
            if vc.modalPresentationStyle == .overFullScreen {
                // 这里手动beginAppearanceTransition触发页面生命周期
                navigationController.topViewController?.beginAppearanceTransition(true, animated: false)

                vc.dismiss(animated: true) {
                    self.navigationController.topViewController?.endAppearanceTransition()
                }
            } else {
                // 正常场景，直接dismiss
                vc.dismiss(animated: true, completion: nil)
            }
        } else {
            navigationController.popViewController(animated: true)
        }
        // 否则直接执行pop逻辑
        // 这里在pop的时候将参数带出,并且从结果表中移除
        if let onPageFinshed = resultTable[options.pageName] {
            onPageFinshed(options.arguments)
            resultTable.removeValue(forKey: options.pageName)
        }
    }

    // MARK: - help

    // 生成路由页面
    func routeViewController(_ pageName: String!, arguments: [AnyHashable: Any]!) -> UIViewController {
        guard let appName = Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String else {
            return UIViewController()
        }
        let className = appName + "." + pageName
        guard let vcClass = NSClassFromString(className) as? UIViewController.Type else {
            return UIViewController()
        }

        let viewController: UIViewController = vcClass.init()
        // 配置参数
        for (key, value) in arguments {
            guard let keyString = key as? String, keyString.count > 0 else {
                continue
            }
            let firstWord = keyString[keyString.startIndex].uppercased()
            let range = keyString.index(after: keyString.startIndex) ..< keyString.endIndex
            let otherWord = keyString[range]
            let destMethodName = "set" + firstWord + otherWord

            if viewController.responds(to: Selector(destMethodName)) {
                var finalVal = value
                // 如果是string类型 ，需要decode
                if value is String {
                    let strVal = value as! String
                    finalVal = String(describing: strVal.cString(using: String.Encoding.utf8))
                }
                viewController.setValue(finalVal, forKey: keyString)
            }
        }
        return viewController
    }

    // 当前Nav控制器
    func topNavigation(_ viewController: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UINavigationController? {
        if let nav = viewController as? UINavigationController {
            return nav
        }
        if let tab = viewController as? UITabBarController {
            if let selected = tab.selectedViewController {
                return topNavigation(selected)
            }
        }
        return viewController?.navigationController
    }
}
